# -*-coding = utf-8 -*-
# @Time : 2023/3/16 19:07
# @Author : Oliver
# @File : py数学库.py
# @Software :PyCharm
import math
from time import time

import numpy as np
import matplotlib.pyplot as plt

# 生成10行2列的随机矩阵 范围0-1
data = np.random.rand(10000, 2)
# print(data)

# 取第0列
# print(data[:, 0])
x = data[:, 0]
# 取第1列
# print(data[:, 1])
y = data[:, 1]

# 控制 只输出在单位圆内的点
idx = x ** 2 + y ** 2 < 1
# idx = [False  True False ...  True  True  True]
# print(idx)
# 半径为0.5内的圆不显示
hole = x ** 2 + y ** 2 < 0.25
# 逻辑与运算 在idx内且不在hole内的点为新的idx
idx = np.logical_and(idx, ~hole)

# go代表绿色 圆点
# ro代表红色 圆点
plt.plot(x[idx], y[idx], 'ro', markersize=1)
# plt.show()

# 直方图
p = np.random.rand(10000)
# edgecolor柱子描边
plt.hist(p, bins=20, color='g', edgecolor='k')
# plt.show()

# 中心极限定理验证 均匀分布累加得到正态分布
N = 10000
times = 100
z = np.zeros(N)
# 将均匀分布的随机值累加100次再除以100 得到的数据分布情况
for i in range(times):
    z += np.random.rand(N)
z /= times
plt.hist(z, bins=20, color='g', edgecolor='k')
# plt.show()

# 5行5列，数据在0-255之间的均匀分布
p = np.random.uniform(0, 255, size=(5, 5))
# print(p)

# 画y=x**x
x = np.arange(0, 20, 1)
y = x ** x
# print(y)
plt.plot(x, y, 'r')
plt.show()


# 本福特定律
# 计算1-N阶乘中，首位数字出现的概率
def first_factorial(N):
    def first_digit(x):
        # 计算x的第一位数字
        # while x >= 10:
        #     x //= 10
        # return x
        return int(str(x)[0])

    n = 1
    frequency = [0] * 9
    for i in range(1, N):
        n *= i
        m = first_digit(n) - 1
        frequency[m] += 1
    print('frequency:', frequency)
    # 1出现的概率占总数的1/3
    # [293, 176, 124, 101, 69, 87, 51, 51, 47]
    plt.plot(frequency, 'r-o')
    plt.show()


first_factorial(1000)


# 计算质数
def cal_sushu():
    a = 2
    b = 100000

    # 暴力解法
    t = time()
    # 在2到math.sqrt(p)范围内都不存在数字能够整除数字p，则p为质数
    p = [p for p in range(a, b) if 0 not in [p % d for d in range(2, int(math.sqrt(p)) + 1)]]
    print('暴力耗时：', time() - t)

    # 定义法
    t = time()
    p_list = []
    for i in range(2, b):
        flag = True
        for p in p_list:
            if p > math.sqrt(i):
                break
            if i % p == 0:
                flag = False
                break
        if flag:
            p_list.append(i)
    print('定义耗时：', time() - t)


cal_sushu()
